<?php

namespace app\common\service\media;

use app\common\model\media\Media;
use app\common\model\media\MediaAccount;
use app\common\model\media\MediaAuth;
use think\facade\Cache;
use think\facade\Log;
use ToutiaoSdk\ToutiaoAuth;
use ToutiaoSdk\TouTiaoClient;

/**
 *
 * 微信开放平台授权登录接口服务
 */
class OceanengineService
{
    protected $config;
    protected $app_id;
    protected $secret;

    const BASE_URL = 'https://api.oceanengine.com/open_api/';

    const REDIS_MEDIA_JL_TOKEN     = 'redis_media_jl_token_';
    const REDIS_MEDIA_JL_REF_TOKEN = 'redis_media_jl_ref_token_';

    public function __construct($authId)
    {
        $mediaAuth    = MediaAuth::where('id', $authId)->findOrEmpty();
        $this->config = config('media.jl') ?? [];
        $this->app_id = $mediaAuth->app_id ?? null;
        $this->secret = $mediaAuth->secret ?? null;
    }

    /*
     * 构建微信请求链接
     * */
    public function getBuildUrl($path, $query)
    {
        $url = self::BASE_URL . ltrim($path, '/') . '?' . http_build_query($query);
        //		$url = self::BASE_URL . ltrim($path, '/');
        return $url;
    }


    /**
     * 获取授权链接
     *
     * @param string $state
     * @return string
     */
    public function getEmpowerUrl($state = 0)
    {
        $redirect_uri = env('app.host') . $this->config['redirect_uri'];
        return sprintf(
            $this->config['empower_url'] ?? '',
            $this->app_id,
            urlencode($redirect_uri),
            $state
        );
    }


    /**
     * 获取缓存token
     *
     * @param $advertiserId
     * @return mixed|string|void
     */
    public function getCacheToken($advertiserId)
    {
        if ($accessToken = Cache::get(self::REDIS_MEDIA_JL_TOKEN . $advertiserId)) {

            return $accessToken;
        }
        // token过期刷新快手token
        if ($refToken = Cache::get(self::REDIS_MEDIA_JL_REF_TOKEN . $advertiserId)) {
            if ($accessToken = $this->refreshToken($refToken)) {

                return $accessToken;
            }
        }


        return '';
    }


    /**
     * 缓存巨量token
     *
     * @param $data
     * @return bool|mixed|string
     */
    public function cacheToken($data)
    {
        Log::write('缓存巨量授权Token==>' . json_encode($data), 'info');
        $accessToken          = $data['access_token'] ?? '';
        $accessTokenExpiresIn = $data['expires_in'] ?? 0;
        $refToken             = $data['refresh_token'] ?? 0;
        $refTokenIn           = $data['refresh_token_expires_in'] ?? 0;
        if (!$advertiserId = $data['advertiser_id'] ?? '') {
            $advertiserId = $data['advertiser_ids'][0] ?? '';
        }

        if (!$accessToken || !$accessTokenExpiresIn || !$refToken || !$refTokenIn) {

            return false;
        }

        // 缓存巨量Token
        Cache::set(self::REDIS_MEDIA_JL_TOKEN . $advertiserId, $accessToken, $accessTokenExpiresIn);
        Cache::set(self::REDIS_MEDIA_JL_REF_TOKEN . $advertiserId, $refToken, $refTokenIn);

        return $accessToken;
    }


    /*
     * 获取accessToken
     * */
    public function getAccessToken($auth_code)
    {
        $auth   = new ToutiaoAuth($this->app_id, $this->secret);
        $json   = $auth->getAccessToken($auth_code);
        $result = json_decode($json, true);
        Log::write('获取巨量授权Token==>', 'info');

        $data = $result['data'] ?? [];
        if (!$accessToken = $this->cacheToken($data)) {

            return false;
        }

        return $result;
    }


    /*
     * 刷新accessToken
     * */
    public function refreshToken($refresh_token)
    {
        $auth   = new ToutiaoAuth($this->app_id, $this->secret);
        $json   = $auth->refreshToken($refresh_token);
        $result = json_decode($json, true);
        Log::write('刷新巨量授权Token==>', 'info');

        $data = $result['data'] ?? [];
        if (!$accessToken = $this->cacheToken($data)) {

            return false;
        }

        return $accessToken;
    }


    /**
     * 获取广告主
     *
     * @param $access_token
     * @param $advertiser_id
     * @return mixed
     */
    public function getAdvertiser($access_token, $advertiser_id)
    {
        $client = TouTiaoClient::getInstance($access_token, null, null, null);

        $args   = ['advertiser_id' => $advertiser_id];
        $req    = $client::Advertiser()->majordomoAdvertise()->setArgs($args)->send();
        $json   = $req->getBody();
        $result = json_decode($json, true);

        return $result;
    }


    /**
     * 更新授权广告主
     *
     * @param $tokenData
     * @param $state
     * @return int
     */
    public function saveAdvertiser($authId, $tokenData)
    {
        $advertiser_ids = $tokenData['data']['advertiser_ids'];
        if (!$authAdvertiserId = $tokenData['data']['advertiser_id'] ?? '') {
            $authAdvertiserId = $tokenData['data']['advertiser_ids'][0] ?? '';
        }
        $access_token      = $tokenData['data']['access_token'];
        $advertiser_id_arr = [];
        foreach ($advertiser_ids as $k => $v) {
            $advertiser = $this->getAdvertiser($access_token, $v);
            if ($advertiser['code'] == 0) {
                foreach ($advertiser['data']['list'] as $key => $value) {
                    $advertiser_id_arr[] = $value;
                }
            }
        }
        $insertData = [];
        foreach ($advertiser_id_arr as $k => $v) {
            if (MediaAccount::where('advertiser_id', $v['advertiser_id'] ?? 0)->where('media_id', Media::SOURCE_JL)->findOrEmpty()->isEmpty()) {
                $insertData[] = [
                    'media_auth_id'      => $authId,
                    'auth_advertiser_id' => $authAdvertiserId,
                    'advertiser_id'      => $v['advertiser_id'],
                    'advertiser_name'    => $v['advertiser_name'],
                    'media_id'           => Media::SOURCE_JL,
                    'create_time'        => time(),
                    'update_time'        => time()
                ];
            }
        }

        return MediaAccount::insertAll($insertData);
    }


    /*
     * 获取用户信息
     * */
    public function requestUserinfo($access_token, $openid)
    {
        $json = $this->getBuildUrl('sns/userinfo', array(
            'access_token' => $access_token,
            'openid'       => $openid
        ));
        return $json;
    }


    /**
     * 获取广告主成本
     *
     * @param $authId
     * @param $advertiserId
     * @param $date
     * @return int
     */
    public function getAdvertiserReport($authId, $advertiserId, $date)
    {
        try {
            if (!$accessToken = $this->getCacheToken($authId)) {

                return 0;
            }

            $args = [
                'advertiser_id' => $advertiserId,
                'start_date'    => $date,
                'end_date'      => $date
            ];

            $client = TouTiaoClient::getInstance($accessToken, null, null, null);
            $result = $client::Report()->advertiserGet()->setArgs($args)->send();
            $data   = json_decode($result->getBody(), true);
            if (!$list = $data['data']['list'] ?? []) {

                return 0;
            }

            $costMoney = 0;
            foreach ($list as $item) {
                $costMoney += $item['cost'] ?? 0;
            }

            if ($costMoney) {

                return $costMoney;
            }

            return 0;
        } catch (\Exception $exception) {
            Log::write('拉取巨量成本报表失败：' . $exception->getMessage(), 'error');

            return 0;
        }
    }
}
